作業ログ | 全てのKeyboardEventとCompositionEventを握りつぶす
2022-04-25
13:16:02
これで一旦試してみる
code:sh
code:test.ts
import { useStatusBar, textInput, takeCursor, insertText } from "../scrapbox-userscript-std/dom.ts";
let mode: "normal" | "input" = "normal";
const execNormal = (command: string) => {
const cursor = takeCursor();
switch (command) {
case "h":
cursor.goByAction("go-left");
return;
case "j":
cursor.goByAction("go-down");
return;
case "k":
cursor.goByAction("go-up");
return;
case "l":
cursor.goByAction("go-right");
return;
case "i":
mode = "input";
return;
}
}
const execInput = (command: string) => {
const cursor = takeCursor();
switch (command) {
case "<C-[>":
case "<Esc>":
mode = "normal";
return;
default:
insertText(command);
return;
}
}
let message = [] as string[];
const log = useStatusBar();
mode = "normal";
const { render, dispose } = useStatusBar();
render({ type: "text", text: mode });
for await (const command of commandWatcher(textInput()!)) {
message.push(command);
if (message.length > 10) message.shift();
switch (mode as "normal" | "input") {
case "normal":
execNormal(command);
break;
case "input":
execInput(command);
break;
}
log.render({ type: "text", text: message.join("") });
render({ type: "text", text: mode });
}
log.dispose();
dispose();
矢印キーとcomposition eventを握りつぶせれれれなかった
14:03:20 握りつぶせなかった……
14:10:35 そもそも握りつぶせるのか?
14:13:45 あり?これで矢印キーなら握りつぶせるっぽい……
code:js
document.getElementById("editor").addEventListener("keydown", e => {
if (!e.isTrusted) return;
e.preventDefault();
e.stopPropagation();
console.log(e);
})
あ、keydownイベントをdocumentでlistenしようとしていたからだ
これも#editorや#text-inputでlistenすれば握りつぶせる
#editorだと止まらない
code:js
document.getElementById("editor").addEventListener("compositionend", e => {
if (!e.isTrusted) return;
e.preventDefault();
e.stopPropagation();
console.log(e);
});
#text-inputでも無理
code:js
document.getElementById("text-input").addEventListener("compositionend", e => {
if (!e.isTrusted) return;
e.stopPropagation();
console.log(e);
});
ただし、#text-inputにcompositionendが送られないせいで、convert-modeが中断されず、入力がおかしなことになる code:js
document.addEventListener("compositionend", e => {
if (!e.isTrusted) return;
if (e.target.id !== "text-input") return;
e.stopPropagation();
console.log(e);
}, { capture: true });
const event = new CompositionEvent("compositionend", { data: "" });document.getElementById("text-input").dispatchEvent(event);で終了イベントを送ると、直前の文字列が流し込まれてしまう
どうやらdataを#text-input側で保持していて、compositionendの値は使われないようだ
HTMLTextareaElement.valueを消してから偽装eventを発行したら成功した!
mobileは未確認。ソースを見てみると、HTMLTextareaElement.valueの値を入力しているようだから、同様に成功すると思う
code:js
document.addEventListener("compositionend", e => {
if (!e.isTrusted) return;
if (e.target.id !== "text-input") return;
e.stopPropagation();
console.log(e);
document.getElementById("text-input").value = "";
const event = new CompositionEvent("compositionend", { data: "" });
document.getElementById("text-input").dispatchEvent(event);
}, { capture: true });